package com.health.mapp.impl;


import java.security.MessageDigest;
import java.util.UUID;

import org.apache.log4j.Logger;

import com.health.commons.CommonsUtils;
import com.health.mapp.bean.Header;
import com.health.mapp.exception.MappException;
import com.health.mapp.service.SecureUtil;
import com.health.mapp.utils.Constant;

/**
 * 消息头校验
 * @author bobo
 *
 */
public class HeaderCheckImpl {

	private static Logger logger = Logger.getLogger(HeaderCheckImpl.class);
	
	public static void execute(Header header) throws MappException {
		//logger.debug("##");
		//校验头部对象是否序列化和反序列化
		CommonsUtils.dumpObject(logger, header);

		//客户端生成的签名
		String headerSign = header.getSign();
		
		//IOS未接入sign
		if (headerSign.equals("2976b2f3db9530e0de8097c1c912550f")) {
			return;
		}
		logger.debug("headerSign:"+ headerSign);
		//根据头部的 API输入参数签名结果进行 安全校验
		if (null != headerSign && 0 < headerSign.length()) {
			try {
				
				String uuid = header.getUuId();
				
				String timeStamp = header.getTimestamp();
				
				//uuid的最后签名位取
				//long number = Math.abs(UUID.fromString(uuid).getLeastSignificantBits());
				
				//判断UUID
				UUID.fromString(uuid);
				
				long number = Long.valueOf(timeStamp);
				//对10取模
				int index = (int)(number % 10);
				//签名内容=appId+version+method+timestamp+uuId +固定长度串（每个请求不一样）。
				String msg = header.getAppId() + header.getVersion() + header.getMethod() + header.getTimestamp() + uuid + SecureUtil.getChallenge(index);
				//信息摘要
				MessageDigest md5 = MessageDigest.getInstance("MD5");
				//使用指定的 byte 数组更新摘要
				md5.update(msg.getBytes());
				//通过执行诸如填充之类的最终操作完成哈希计算。
				byte[] buffer = md5.digest();
				//bcd码转为String
				String sign = bcd2Str(buffer);
			    logger.debug("sign:"+ sign);
				//如果生成的签字和客户端送来的不一致，验证签名失败
				if (true != sign.equalsIgnoreCase(headerSign)) {
					throw new MappException(Constant.CODE_REQ_JSON_SIGN_ERR, Constant.MSG_REQ_JSON_SIGN_ERR);
				}
			} catch (Exception e) {
				e.printStackTrace();
				
				throw new MappException(Constant.CODE_REQ_JSON_SIGN_ERR, Constant.MSG_REQ_JSON_SIGN_ERR);
			}
		}
		
		// 请求方法为空
		if (header.getMethod() == null || header.getMethod().trim() == "") {
			throw new MappException(Constant.CODE_REQ_METHOD_NULL, Constant.MSG_REQ_METHOD_NULL);
		}
	}
	
	private static String bcd2Str(byte[] bytes) {
		char temp[] = new char[bytes.length * 2], val;

		for (int i = 0; i < bytes.length; i++) {
			val = (char) (((bytes[i] & 0xf0) >> 4) & 0x0f);
			temp[i * 2] = (char) (val > 9 ? val + 'A' - 10 : val + '0');

			val = (char) (bytes[i] & 0x0f);
			temp[i * 2 + 1] = (char) (val > 9 ? val + 'A' - 10 : val + '0');
		}
		
		return new String(temp);
	}
}
